import javax.swing.*;
import java.awt.*;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;

/**
 * DrawFace.java This class will draw the face of a sundial based on values passed in
 * @author Arun Lee, Michael Terada, Marek Lopez
 *
 */
public class DrawFace extends JFrame implements Printable {

    double[] hours;
    String[] stringHours;
    boolean  southernHem = false; //If the user is in the southern hemisphere
    //Default is false, will change if not
    int      length;
    double   lat;                 //If latitude passed is negative, must print hours in reverse

    //default; should never execute
    public DrawFace() {
        this.hours = null;

        setTitle("Face Error");
        setSize(400, 400);
        setVisible(true);
        setBackground(Color.white);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    }

    public DrawFace(double[] hourLines, double latitude, int len) {
        Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
        this.hours = hourLines;
        this.lat = latitude;
        this.length = len;
        //check for negative latitude
        if (this.lat < 0) {
            this.southernHem = true;
        }
        //Set parameters of jFrame
        setTitle("Sundial Face");
        setSize(size);
        setVisible(true);
        setBackground(Color.white);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    }

    public void paint(Graphics canvas) {
        if (hours == null) {
            //Should never execute; just error checking
            canvas.drawString("Hours array is null", 150, 200);
        } else {
            // Put the right hours in for printing
        	stringHours     = new String[]{"6", "7", "8", "9", "10", "11", "12", "1", "2", "3", "4", "5", "6"};
            int endX;
            int endY;
            int startBaseX  = 25;
            int startBaseY  = 400;
            int endBaseX    = startBaseX + this.length * 2;
            int endBaseY    = startBaseY;//Need base to be straight
            int middleBaseX = ((endBaseX - startBaseX) / 2) + startBaseX;
            int middleBaseY = startBaseY;
            int k           = 0; //For iterating through the stringHour array

            canvas.setFont(new Font("TimesRoman", Font.PLAIN, 20));
            //baseline
            canvas.drawLine(startBaseX, startBaseY, endBaseX, endBaseY);
            //Check if hours need to be printed in reverse
            if (southernHem == true) {
                for (int i = 0; i < hours.length; i++) {
					 if((i % 2) == 0){
	                    endX = (int) (middleBaseX - this.length * Math.sin(Math.toRadians(hours[i])));
	                    endY = (int) (middleBaseY - this.length * Math.cos(Math.toRadians(hours[i])));
	                    canvas.drawLine(middleBaseX, middleBaseY, endX, endY);
	                 }
					 else {
						 endX = (int) (middleBaseX - this.length/2 * Math.sin(Math.toRadians(hours[i])));
		                 endY = (int) (middleBaseY - this.length/2 * Math.cos(Math.toRadians(hours[i])));
		                 canvas.drawLine(middleBaseX, middleBaseY, endX, endY);
					 }
						  //Draw the hour numbers every other line
                    if ((i % 2) == 0) {
                        canvas.drawString(stringHours[k], endX, endY);
                        k++;
                    }
                }
                canvas.drawLine(middleBaseX, middleBaseY, middleBaseX, middleBaseY - this.length - 20);
                canvas.drawString("S", middleBaseX - this.length + 50 , middleBaseY - this.length + 50);
                canvas.drawString("/\\", middleBaseX - this.length + 50 , middleBaseY - this.length + 70);
            } else { //Not in southern hemisphere
                //Go through hours and draw a line for each degree
                for (int i = 0; i < hours.length; i++) {
                    if((i % 2) == 0){
                    	endX = (int) (middleBaseX - this.length * Math.sin(Math.toRadians(-hours[i])));
                        endY = (int) (middleBaseY - this.length * Math.cos(Math.toRadians(-hours[i])));
                        canvas.drawLine(middleBaseX, middleBaseY, endX, endY);
                    }
                	else{
                		endX = (int) (middleBaseX - this.length/2 * Math.sin(Math.toRadians(-hours[i])));
	                    endY = (int) (middleBaseY - this.length/2 * Math.cos(Math.toRadians(-hours[i])));
	                    canvas.drawLine(middleBaseX, middleBaseY, endX, endY);
                	}
						  //Draw the hour numbers every other line
                    if ((i % 2) == 0) {
                        canvas.drawString(stringHours[k], endX, endY);
                        k++;
                    }
                }
                canvas.drawLine(middleBaseX, middleBaseY, middleBaseX, middleBaseY - this.length - 20);
                canvas.drawString("N", middleBaseX - this.length + 50 , middleBaseY - this.length + 50);
                canvas.drawString("/\\", middleBaseX - this.length + 50 , middleBaseY - this.length + 70);
            }
        }
    }

    /**
     * Required by Printable interface.
     * @param g
     * @param pf
     * @param page
     * @return
     * @throws PrinterException
     */
    public int print(Graphics g, PageFormat pf, int page)
            throws PrinterException {

        // We have only one page, and 'page'
        // is zero-based
        if (page > 0) {
            return NO_SUCH_PAGE;
        }

        // User (0,0) is typically outside the
        // imageable area, so we must translate
        // by the X and Y values in the PageFormat
        // to avoid clipping.
        Graphics2D g2d = (Graphics2D) g;
        g2d.translate(pf.getImageableX(), pf.getImageableY());

        // Now we perform our rendering
        //This prints a grey page with the applet name at the top, but no lines.
        //why no lines?
        this.paint(g2d);

        // tell the caller that this page is part
        // of the printed document
        return PAGE_EXISTS;
    }
}
